<template>
  <FormProvider :form="form">
    <SchemaField :schema="schema" :scope="funcMapScope" />
  </FormProvider>
</template>
  
  <script>
// 引入formily
import { createForm } from "@formily/core";
import { FormProvider, createSchemaField } from "@formily/vue";
import { action } from "@formily/reactive";
import {
  Input,
  Password,
  Select,
  DatePicker,
  TimePicker,
  InputNumber,
  Transfer,
  Cascader,
  Radio,
  Checkbox,
  Upload,
  Switch,
  Form,
  FormLayout,
  FormItem,
  FormGrid,
  FormButtonGroup,
  Space,
  Submit,
  Reset,
  ArrayCards,
  ArrayItems,
  ArrayTable,
  ArrayTabs,
  FormCollapse,
  FormStep,
  FormTab,
  FormDialog,
  FormDrawer,
  Editable,
} from "@formily/element";
import { getSchema, extractFunctionsFromSchema } from "@/utils/schema.js";

// 注册formily组件
let { SchemaField } = createSchemaField({
  components: {
    Input,
    Password,
    Select,
    DatePicker,
    TimePicker,
    InputNumber,
    Transfer,
    Cascader,
    Radio,
    Checkbox,
    Upload,
    Switch,
    Form,
    FormLayout,
    FormItem,
    FormGrid,
    FormButtonGroup,
    Space,
    Submit,
    Reset,
    ArrayCards,
    ArrayItems,
    ArrayTable,
    ArrayTabs,
    FormCollapse,
    FormStep,
    FormTab,
    FormDialog,
    FormDrawer,
    Editable,
  },
});

export default {
  name: "Formily",
  props: {
    schemaCode: {
      type: String,
      default: "002",
    },
  },
  watch: {
    schemaCode(newValue) {
      this.getSchemaConfig(newValue);
    },
  },
  components: { SchemaField, FormProvider },
  data() {
    let form = createForm();
    return {
      form,
      schema: null,
      action,
      funcMapScope: {},
    };
  },
  created() {
    this.getSchemaConfig(this.schemaCode);
  },
  methods: {
    getSchemaConfig(value) {
      // 获取 schema
      const schema = getSchema(value);

      this.schema = schema;

      // 提取函数，传递组件实例（this）
      const funcMap = {};
      extractFunctionsFromSchema(schema, funcMap, this);

      // 将 funcMap 中的函数添加到组件的 $options.methods 中
      this.$options.methods = {
        ...this.$options.methods,
        ...funcMap,
      };

      this.funcMapScope["vueThis"] = this;

      // 如果需要在 funcMapScope 中使用这些函数
      this.funcMapScope = { ...this.funcMapScope, ...funcMap };
    },
    getForm(){
      return this.form;
    }
  },
};
</script>